<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>推导 promise</title>
  </head>
  <body>
    <script>
      // 1. 闭包
      // 函数作用域，函数内部可以访问外部的引用
      // 等号右边的是值，等号左边的是引用
      // 右值，左值
      // 栈值，堆值
      // 为什么 js 函数，有这个特性呢？
      //   let a = 1;
      //   function test() {
      //     // 能够访问到 a，引用
      //     console.log(a);
      //   }

      // 2. 异步闭包
      // 引用：存储一个值的地址，就像一个箭头，指向了值
      //   let a = 1;
      // 并列的异步，是同步触发的，比如setTimeout函数本身，回调是异步的
      // 函数闭包，专门为了异步存在
      // 函数可以访问，外部特定时刻的**引用** —— 时间线
      //   setTimeout(() => {
      //     console.log(a);
      //     a = 2;
      //   }, 1000);
      //   setTimeout(() => {
      //     console.log(a);
      //   }, 2000);

      // 观察**值**
      // a -> {value -> 1}
      // value2 -> 1
      // 取引用但取不到值的情况
      //   const a = { value: 1 };
      //   const value2 = a.value; // a.value 是右值
      //   // const {value} = a // 解构赋值
      //   setTimeout(() => {
      //     console.log(value2);
      //     a.value = 2;
      //   }, 1000);
      //   setTimeout(() => {
      //     console.log(value2);
      //   }, 2000);
      // xhr/setTimeout 是不是都有取值和取引用的问题
      //   const xhr = new XMLHttpRequest();
      //   const { readyState } = xhr;
      //   xhr.onreadystatechange = () => {
      //     if (readyState === 4) {
      //     }
      //   };

      // 3. 函数当作参数传递（回调），在异步结果中调用（异步回调）
      // 函数作用域，是回调处理异步的基础
      // 因为函数作用域存在，所以回调在异步中调用时，可以拿到**最新**的引用
      // 1
      //   let a = 1;
      //   function wait(cb) {
      //     setTimeout(
      //       // 一秒以后调用
      //       () => {
      //         cb();
      //       },
      //       1000
      //     );
      //   }
      //   function callback() {
      //     console.log(a);
      //   }
      //   //2
      //   wait(callback);
      //   //3
      //   a = 2;

      // 4. 异步回调的回调地狱
      // 1秒之后，打印数据，这之后再一秒，打印数据，再等一秒，再打印数据
      // 因为函数作用域存在，会存在：1. 取值取引用问题，2. 常量冲突，3. 变量遮蔽，4.大椎形代码
      // 需要解决这个问题 —— 等待一段时间，干一件事，再等待一段时间 —— 回调地狱
      //   const a = { value: 1 };
      //   const { value } = a;
      //   wait(() => {
      //     // 常量冲突
      //     const b = 1;
      //     console.log(1);
      //     wait((res) => {
      //       console.log(2);
      //       // 变量遮蔽
      //       wait((res) => {
      //         console.log(res);
      //         console.log(3);
      //         b = 2;
      //       });
      //     });
      //   });

      // 软件开发没有银弹 回调地狱很磨人，解决回调需要 Promise，Promise 使用简单，烧脑袋
      // 5. Promise
      // 往 等待一段时间（api）里面传，避开主体函数
      // getPromise().then(()=>{})
      // 单个 promise
      // promise 形式
      //   new Promise((resolve, reject) => {
      //     setTimeout(() => {
      //       resolve("等待1秒"); // .then 的回调，在这里跑
      //     }, 1000);
      //     // 然后 / 一段时间以后
      //   }).then(
      //     // 作用域在外面，只有resolve 里面的数据 按值传递
      //     (res) => {
      //       console.log(res); // 等待1秒
      //     }
      //   );
      // 封装 promise
      //   function wait(n) {
      //     return new Promise((resolve, reject) => {
      //       setTimeout(() => {
      //         resolve(`等待${n}毫秒`); // .then 的回调，在这里跑
      //       }, n);
      //       // 然后 / 一段时间以后
      //     });
      //   }
      // // 回调形式
      // function wait2(cb) {
      //   setTimeout(() => {
      //     cb();
      //   }, 1000);
      // }
      // function callback() {
      //   console.log("等待1秒");
      // }
      // wait2(callback);
      // wait(1000).then((res) => {
      //   console.log(res);
      // });

      // 6.promise 链式调用
      // 等待一段时间，干一件事，再等待一段时间，再干一件事 ...
      // arr.map().map()
      // promise().then().then()
      // function wait(n) {
      //   return new Promise((resolve, reject) => {
      //     setTimeout(() => {
      //       resolve(`等待${n}毫秒`); // .then 的回调，在这里跑
      //     }, n);
      //     // 然后 / 一段时间以后
      //   });
      // }
      // wait(1000)
      //   .then((res) => {
      //     console.log(res);
      //     // 当 .then 返回的值是 promise，下一个.then（的参数）是promise的resolve
      //     return wait(1000);
      //   })
      //   .then((res) => {
      //     console.log(res);
      //     // 当 .then 返回的值，不是 promise 的时候，下一个 .then 就是这个值
      //     return "立即执行";
      //   })
      //   .then((res) => {
      //     console.log(res);
      //   });

      // fetch promise 链式调用
      // fetch 连续请求，就是在第二段 then 中，返回新的 fetch
      // fetch().then().then(()=>fetch()).then().then()
    </script>
  </body>
</html>
